﻿// <copyright file="SociologicalData.cs" company="QUT">
//     Copyright (c) Ninety Nine Percent. All rights reserved.
// </copyright>

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq;
using System.IO;
using System.Linq;
using System.Text;
using FileHelpers.DataLink;
using Qut.GenerateKml.Data.FileDefinitions;

namespace Qut.GenerateKml.Data
{      
    /// <summary>
    /// Component for managing sociological data.
    /// </summary>
    public class SociologicalData : ISociologicalData, IDisposable
    {
        /// <summary>
        /// Sociological data classes data context.
        /// </summary>
        private SociologicalDataClassesDataContext _database;

        /// <summary>
        /// Initializes a new instance of the SociologicalData class.
        /// </summary>
        public SociologicalData()
        {
        }

        /// <summary>
        /// Gets the Sociological data classes data context.
        /// </summary>
        /// <value>The database.</value>
        public SociologicalDataClassesDataContext Database
        {
            get
            {
                if (this._database == null)
                {
                    this._database = new SociologicalDataClassesDataContext();
                }

                return this._database;
            }
        }

        /// <summary>
        /// Loads the sociological data file at the specified file path.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        public void PreloadFederalElectionResultsQld2004(string filePath)
        {
            FederalElectionResultsQld2004FileDefinition.Load(filePath, this.Database);
        }

        /// <summary>
        /// Preloads the QLD federal results2 party preferred by electorate2004.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        public void PreloadQldFederalResults2PartyPreferredByElectorate2004(string filePath)
        {
            this.TestFile(filePath);
            QldFederalResults2PartyPreferredByElectorate2004FileDefinition.Load(filePath, this.Database);
        }

        /// <summary>
        /// Preloads the QLD federal results by electorate2004.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        public void PreloadQldFederalResultsByElectorate2004(string filePath)
        {
            this.TestFile(filePath);
            QldFederalResultsByElectorate2004FileDefinition.Load(filePath, this.Database);
        }

        /// <summary>
        /// Preloads the QLD federal state electorate mapping.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        public void PreloadQldFederalStateElectorateMapping(string filePath)
        {
            this.TestFile(filePath);
            QldFederalStateElectorateMappingFileDefinition.Load(filePath, this.Database);
        }

        /// <summary>
        /// Preloads the QLD state results by electorate2006.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        public void PreloadQldStateResultsByElectorate2006(string filePath)
        {
            this.TestFile(filePath);
            QldStateResultsByElectorate2006FileDefinition.Load(filePath, this.Database);
        }

        /// <summary>
        /// Gets any division which are not matching divisions in geographic data
        /// </summary>
        /// <param name="mapInfo">The geographic data.</param>
        /// <returns>List of missing division</returns>
        public List<string> GetMissingDivision(MapInfoFile mapInfo)
        {
            DataTable midData = mapInfo.GetMidData();
            List<string> missingDivisions = new List<string>();
            bool missingDivision;

            // Search for geographic divisions which are found in sociological data or not
            var results = from r in this.Database.QldFederalResultsByElectorate2004s
                          select r;
            foreach (var result in results)
            {
                missingDivision = true;
                string division = result.Division;
                foreach (DataRow row in midData.Rows)
                {
                    string division2 = row[1].ToString();
                    if (division.ToLower() == division2.ToLower())
                    {
                        missingDivision = false;
                        break;
                    }
                }

                if (missingDivision)
                {
                    missingDivisions.Add(division.Trim() + " is not found. The sociological information about this division will not be displayed in Google Earth.");
                }
            }

            return missingDivisions;
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (this._database != null)
            {
                this._database.Dispose();
            }
        }

        /// <summary>
        /// Tests the file.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        private void TestFile(string filePath)
        {
            FileInfo file = new FileInfo(filePath);
            if (!file.Exists)
            {
                throw new FileNotFoundException("The file specified does not exist.", filePath);
            }

            if (file.Length == 0)
            {
                throw new ApplicationException(string.Format("The file specified ({0}) is empty.", filePath));
            }
        }
    }
}
